# Player Returner

import os
import commands

# Each Player has this methods:
#    - Current
#    - Elapsed
#    - Length
#    - Status

class Audacious:
    def __init__(self):
        self.cmds = {
            "current" : "current-song",
            "elapsed" : "current-song-output-length-frames",
            "length"  : "current-song-length-seconds",
            "status"  : "playback-status" }
    
    def Get(self,command):
        return commands.getoutput("audtool %s" %self.cmds[command])
    
    def Current(self):
        return self.Get("current")

    def Elapsed(self):
        return float(self.Get("elapsed"))/1000

    def Length(self):
        return int(self.Get("length"))

    def Status(self):
        return self.Get("status")

class Banshee:
    def __init__(self):
        self.cmds = {
            "current" : "--query-title",
            "elapsed" : "--query-position",
            "length"  : "--query-duration",
            "status"  : "--query-status" }
        
    def Get(self,command):
        return commands.getoutput("banshee %s" %self.cmds[command])
    
    def Current(self):
        return self.Get("current")[7:]

    def Elapsed(self):
        return float(self.Get("elapsed")[10:])

    def Length(self):
        return int(self.Get("length")[10:])

    def Status(self):
        st=int(self.Get("status").split(' ')[1])
        
        return ["paused","playing"][st]

class Rhythmbox:
    """MediaPlayer class for Rhythmbox, a Gtk/Gnome media player."""
    def __init__(self):
        try:
            import dbus
        except:
            raise Exception('Rhythmbox is not supported w/o python-dbus bindings.')

        self.cmds = {
            "current" : "unicode(self.properties.get('title', '')).encode('UTF-8')",
            "elapsed" : "self.player.getElapsed()",
            "length"  : "self.properties.get('duration', 0)",
            "status"  : "bool(self.player.getPlaying())" }
        
        bus=dbus.SessionBus()
        
        player_obj = bus.get_object("org.gnome.Rhythmbox", "/org/gnome/Rhythmbox/Player")
        shell_obj  = bus.get_object("org.gnome.Rhythmbox", "/org/gnome/Rhythmbox/Shell")
        
        self.player = dbus.Interface(player_obj, "org.gnome.Rhythmbox.Player")
        self.shell  = dbus.Interface(shell_obj,  "org.gnome.Rhythmbox.Shell")
        uri = unicode(self.player.getPlayingUri())

        self.properties = dict([(unicode(key), val) for key,val in dict(self.shell.getSongProperties(uri)).items()])

    def Get(self,command):
        return eval(self.cmds[command])

    def Current(self):
        return self.Get("current")

    def Elapsed(self):
        return float(self.Get("elapsed"))

    def Length(self):
        return int(self.Get("length"))

    def Status(self):
        st=self.Get("status")

        if st:
            return "playing"
        else:
            return "paused"

class Amarok:
    """MediaPlayer class for Amarok, a Qt/KDE media player.  This implementation is
    a bit messy because it resolves whether or not to use DCOP statically;  after
    importing, the comparissons are made and the appropriate functions are used."""
    def __init__(self):
        
        self.cmds = {
            "current" : "title",
            "elapsed" : "currentTime",
            "length"  : "totalTime",
            "status"  : "" }

    def Get(self,command):
        return commands.getoutput("dcop amarok player %s" % self.cmds[command]).strip()

    def Current(self):
        return self.Get("current")

    def Elapsed(self):
        return float(self.Get("elapsed"))

    def Length(self):
        return int(self.Get("length"))

    def Status(self):
        return

class Juk:
    """MediaPlayer class for Juk, a Qt/KDE media player.  This implementation is
    a bit messy because it resolves whether or not to use DCOP statically;  after
    importing, the comparissons are made and the appropriate functions are used."""
    def __init__(self):
        
        self.cmds = {
            "current" : "trackProperty Title",
            "elapsed" : "currentTime",
            "length"  : "trackProperty Seconds",
            "status"  : "" }

    def Get(self,command):
        return "dcop juk Player %s" % self.cmds[command]
            
    def Current(self):
        return self.Get("current")

    def Elapsed(self):
        return float(self.Get("elapsed"))

    def Length(self):
        return int(self.Get("length"))

    def Status(self):
        return

class Bmpx:
    def __init__(self):
        try:
            import dbus
        except:
            return

        bus=dbus.SessionBus()
        
        self.Player = bus.get_object('org.mpris.bmp', '/Player')

        self.cmds = {
            "current" : "title",
            "elapsed" : "",
            "length"  : "time",
            "status"  : "" }

    def Get(self,command):
        info = self.Player.GetMetadata()
        decode = lambda x: unicode(x).encode('utf-8')
        return decode(info[self.cmds[command]])
            
    def Current(self):
        return self.Get("current")

    def Elapsed(self):
        return

    def Length(self):
        return int(self.Get("length"))

    def Status(self):
        return

class Finder:
    def __init__(self):
        self.players = {
            'audacious' : 'audacious',
#            'bmpx'      : 'beep-media-player-2',
#            'beep'      : 'beep-media-player',
#            'xmms2'     : 'xmms2d',
#            'xmms'      : 'xmms',
            'banshee'   : 'banshee.exe',
            'juk'       : 'juk',
            'amarok'    : 'amarokapp',
            'rhythmbox' : 'rhythmbox',
        }

        self.player=self.find()
            

    def find(self):
        brute=commands.getoutput("ps aux")
        
        for player in self.players.keys():
            if self.players[player] in brute:
                return eval(player.capitalize()+"()")

        return
